//
//  HRRecordAudioViewModel.m
//  Hear
//
//  Created by mac on 2017/3/31.
//  Copyright © 2017年 mac. All rights reserved.
//

#import "HRRecordAudioViewModel.h"
#import <AVFoundation/AVFoundation.h>
#import "HUB.h"
#import "lame.h"
#import "HRRecordButton.h"
#import "HRRecordAudioViewController.h"

//#import "TSLibraryImport.h"

@interface HRRecordAudioViewModel ()<AVAudioRecorderDelegate, AVAudioPlayerDelegate>
{
    NSMutableArray *audioMixParams;
    SystemSoundID _sound;//音效
    AVAssetExportSession* exportSession;
    NSTimer * myTimer;
    NSInteger timeCount;
}
@property (nonatomic, copy)NSString *audioRecordingPath;
@property (nonatomic, assign)BOOL isRecording;
@property (nonatomic, assign)BOOL isAllowRecording;

@property (nonatomic, assign)BOOL isSelect;
@property (nonatomic, copy)NSString *audioPath;
@property(nonatomic, strong)NSString *noChangePath;

@property(nonatomic, strong)NSMutableArray *wavPathMutableArr;
@property(nonatomic, strong)NSMutableData *soundMutableData;

@property(nonatomic, strong)HRRecordButton *hrrecordButton;
@property(nonatomic, strong)HRRecordAudioViewController *hrRecordAudioVC;
@property(nonatomic, strong)NSString *temPath;

@end

@implementation HRRecordAudioViewModel

- (AVAudioRecorder *)audioRecorder {
    if (!_audioRecorder){
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        
        NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithFloat: 44100.0],AVSampleRateKey, //采样率
                                        [NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey, //录音格式
                                        [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数 默认 16
                                        [NSNumber numberWithInt: 2], AVNumberOfChannelsKey,//通道的数目,
                                        [NSNumber numberWithInt:AVAudioQualityHigh],AVEncoderAudioQualityKey, //录音质量
                                        nil];
        
        self.audioPath = [self FilePathInLibraryWithName:@"Caches/UserRecordTemp.wav"];
        
        NSURL *url = [NSURL fileURLWithPath:self.audioPath];
        
        NSError *error = nil;
        
        self.audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];
        [self.audioRecorder setMeteringEnabled:YES];

        if (self.audioRecorder.isRecording) {
            DDLog(@"recording");
        }
    }
    return _audioRecorder;
}

-(NSMutableArray *)wavPathMutableArr {
    if (!_wavPathMutableArr) {
        _wavPathMutableArr = [[NSMutableArray alloc] initWithCapacity:1];

    }
    return _wavPathMutableArr;
}
-(NSMutableData *)soundMutableData {
    if (!_soundMutableData) {
        _soundMutableData = [NSMutableData alloc];
    }
    return _soundMutableData;
}

#pragma 点击录制按钮事件
- (void)recorlAudio {
//    [self stopPlaying];

    if (self.isAllowRecording) {
        if (self.isSelect) {
            self.isSelect = NO;
            [self pause];
        } else {
            self.isSelect = YES;
            [self startRecord];
        }
    }
    
}

#pragma 停止播放
- (void)stopPlaying {
    DDLog(@"stopPlaying");
    [self.audioPlayer stop];
    self.audioPlayer = nil;
}

#pragma 暂停录制
- (void)pause {
    [self.audioRecorder pause];
}

#pragma mark 开始录制
- (void)startRecord {
    
    if (self.isRecording)return;
    
    if (self.isAllowRecording) {
        self.isAllowRecording = YES;
        [self.audioRecorder record];
    }
    
}

- (void)removeRecord {
    [self.audioRecorder stop];
    self.audioRecorder = nil;
    
    self.isRecording = NO;
    
}

#pragma mark -- 停止录制
- (void)stopRecord {
    [MBProgressHUD showHUDAddedTo:WINDOW animated:YES];
    
    dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0/*延迟执行时间*/ * NSEC_PER_SEC));
    
    dispatch_after(delayTime, dispatch_get_main_queue(), ^{
        if (self.recordAudioStopBlock) {
            self.recordAudioStopBlock();
        }
        NSFileManager* fileManager = [NSFileManager defaultManager];
        
        [self.audioRecorder pause];
        
        self.audioRecorder = nil;
        
        self.isRecording = NO;
        
        NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *nowMp3Path = [NSString stringWithFormat:@"%@/NowHear.mp3",documentDir];
        
        [self audio_PCMtoMP3:nowMp3Path andFromPath:self.audioPath];
        
    });
}

#pragma mark --------- 播放
-(void)playRecordingWithPath:(NSString *)RecordPath{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    
    NSURL *url;
    url = [NSURL fileURLWithPath:RecordPath];
    NSError *error;
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    
    if (error != nil){
        [self stopPlaying];
    }else{
        self.audioPlayer.numberOfLoops = 0;
        self.audioPlayer.delegate = self;
        [self.audioPlayer play];
        DDLog(@"playing");
    }
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    self.audioPlayer = nil;
    if (self.audioPlayerDidFinishPlaying) {
        self.audioPlayerDidFinishPlaying();
    }
    
}

- (NSString *)FilePathInLibraryWithName:(NSString *)name {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *LibraryDirectory = [paths objectAtIndex:0];
    return [LibraryDirectory stringByAppendingPathComponent:name];
}

#pragma mark - wav转MP3 -
- (void)audio_PCMtoMP3:(NSString *)mp3Path andFromPath:(NSString *)fromPath {
    
    @try {
        int read, write;
        DDLog(@"mp3Path is %@.......fromPath is %@",mp3Path,fromPath);
        FILE *pcm = fopen([fromPath cStringUsingEncoding:1], "rb"); //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);  //skip file header
        FILE *mp3 = fopen([mp3Path cStringUsingEncoding:1], "wb"); //output 输出生成的Mp3文件位置
        
        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        unsigned char mp3_buffer[MP3_SIZE];
        
        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 44100.0);
        lame_set_VBR(lame, vbr_default);
        lame_init_params(lame);
        
        do {
            read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
            if (read == 0)
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            else
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
            
            fwrite(mp3_buffer, write, 1, mp3);
            
        } while (read != 0);
        
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
    }
    @catch (NSException *exception) {
        DDLog(@"%@",[exception description]);
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:WINDOW animated:YES];
        });
    }
    @finally {
        
        WeakSelf
        
        self.outPutFilePath = mp3Path;
        self.mp3Path = mp3Path;

        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:WINDOW animated:YES];
        });
        DDLog(@"cover=====================");

    }
}

#pragma 是否播放
- (void)playAudioBlock:(BOOL)playAudio {
    if (playAudio) {
        if (self.outPutFilePath) {
            
            [self playRecordingWithPath:self.outPutFilePath];
            return;
        }
        [self playRecordingWithPath:self.audioPath];
    } else {
        [self stopPlaying];
    }
}

-(SystemSoundID)loadSound:(NSString *)soundFileNAme{//(soundFileNAme传值用)
    //需要制定声音的文件路径，这个方法需要加载不同的音效
    NSString *path = [[NSBundle mainBundle]pathForResource:soundFileNAme ofType:nil];
    //将路径字符串转换为url
    NSURL *url = [NSURL fileURLWithPath:path];
    //初始化音效
    //(url - CFURLRef
    // SystemSoundID)
    SystemSoundID soundId;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url),&soundId);
    return soundId;
}


- (void)checkRecord {
    if ([self canRecord]) {
        self.isAllowRecording = YES;
    } else {
        self.isAllowRecording = NO;
    }
}

- (BOOL)canRecord {
    __block BOOL bCanRecord = YES;
    if ([[UIDevice currentDevice].systemVersion doubleValue] > 6.9)
    {
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];  //此处需要恢复设置回放标志，否则会导致其它播放声音也会变小
        if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) {
            [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
                if (granted) {
                    bCanRecord = YES;
                } else {
                    bCanRecord = NO;
                }
            }];
        }
    }
    return bCanRecord;
}

//-(void)dealloc
//{
//    self.audioPlayer = nil;
//    self.audioRecorder = nil;
//}

- (void)startTimeCount {
    WeakSelf
//    self.recordTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f block:^(NSTimer * _Nonnull timer) {
//        if (weakSelf.recordAudioTimeBlock)
//        {
//            weakSelf.recordAudioTimeBlock([NSString stringWithFormat:@"%dS",(int)self.audioRecorder.currentTime]);
//            if (self.audioRecorder.currentTime > 180){
//                [MBProgressHUD showMessage:@"录制最长只能180S" finishBlock:nil];
//                [self.recordTimer invalidate];
//                self.recordTimer = nil;
//                [self recorlAudio];
//            }
//        }
//    } repeats:YES];
    
    
}


#pragma -mark- 选择背景音乐
- (void)addMusicName:(NSString *)musicName {
    if (!self.mp3Path.length) {
        [MBProgressHUD showMessage:@"请先录制一个音频" finishBlock:nil];
        return;
    }
    if ([musicName isEqualToString:@"无音效"]) {
        self.outPutFilePath = self.audioPath;
        [self playRecordingWithPath:self.audioPath];
        return;
    }
    [self audioAndAudio:musicName];
}

- (void)audioAndAudio:(NSString *)musicName {
    
    NSString *audioPath = [[NSBundle mainBundle] pathForResource:musicName ofType:@"mp3"];
    AVURLAsset *audioAsset1 = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:self.mp3Path]];
    AVURLAsset *audioAsset2 = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:audioPath]];
    
    AVMutableComposition *compostion = [AVMutableComposition composition];
    AVMutableCompositionTrack *video = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];
    
    [video insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset1.duration) ofTrack:[audioAsset1 tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];
    
    AVMutableCompositionTrack *audio = [compostion addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];
    DDLog(@">>>>>>>>>>>>>%f>>>>>>>>%f",audioAsset1.duration.value,audioAsset2.duration.value);
    if(audioAsset1.duration.value > audioAsset2.duration.value) {
        CMTime audioDuration = audioAsset1.duration; //录音

        float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
        float audioDurationSeconds2 = CMTimeGetSeconds(audioAsset2.duration);
        
        int count = audioDurationSeconds/audioDurationSeconds2;
        if ((int)(ceil(audioDurationSeconds))%(int)(ceil(audioDurationSeconds2)) != 0) {
            count += 1;
        }
        
        NSMutableArray *rangesArr = [NSMutableArray array];
        NSMutableArray *tracksArr = [NSMutableArray array];
        
        CMTime mp3Duration = audioAsset2.duration;
        for (int i = 0; i < count; i ++) {
            CMTime firstframe= CMTimeMake(0,audioDuration.timescale);
            CMTime secondframe= CMTimeMake(mp3Duration.value,audioDuration.timescale);
            if (i != 0)
            {
                secondframe = CMTimeMake(audioDuration.value-(mp3Duration.value*i),audioDuration.timescale);
            }
            CMTimeRange range = CMTimeRangeMake(firstframe, secondframe);
            
            [rangesArr addObject:[NSValue valueWithCMTimeRange:range]];
            
            [tracksArr addObject:[audioAsset2 tracksWithMediaType:AVMediaTypeAudio].firstObject];
        }
        
        [audio insertTimeRanges:rangesArr ofTracks:tracksArr atTime:kCMTimeZero error:nil];
    } else {
        [audio insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset1.duration) ofTrack:[audioAsset2 tracksWithMediaType:AVMediaTypeAudio].firstObject atTime:kCMTimeZero error:nil];
     }
    
    AVAssetExportSession *session = [[AVAssetExportSession alloc]initWithAsset:compostion presetName:AVAssetExportPresetAppleM4A];
    NSString *outPutFilePath = [self FilePathInLibraryWithName:@"Caches/user/UserAddRecordTemp.m4a"];
    if ([[NSFileManager defaultManager] fileExistsAtPath:outPutFilePath])
    {
        [[NSFileManager defaultManager] removeItemAtPath:outPutFilePath error:nil];
    }
    session.outputURL = [NSURL fileURLWithPath:outPutFilePath];
    session.outputFileType = @"com.apple.m4a-audio";
    session.shouldOptimizeForNetworkUse = YES;
    WeakSelf
    [session exportAsynchronouslyWithCompletionHandler:^{
        if ([[NSFileManager defaultManager] fileExistsAtPath:outPutFilePath]) {
            AVURLAsset* audioAsset =[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:outPutFilePath] options:nil];
            CMTime audioDuration = audioAsset.duration;
            float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
            weakSelf.audioLength = audioDurationSeconds;

            if (weakSelf.addEnditBlock){
                weakSelf.addEnditBlock();
            }
            
        } else {
            DDLog(@"输出错误");
        }
    }];
    
}




@end
